package com.jgp.security.service;

import com.jgp.common.pojo.TreeBean;
import com.jgp.security.secmodel.SecRole;
import com.jgp.security.secrepository.SecRoleRepository;
import com.jgp.sys.query.Operator;
import com.jgp.sys.query.OrderList;
import com.jgp.sys.query.QueryFilterList;
import com.jgp.sys.ui.Pager;
import com.jgp.sys.utils.TreeUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019-11-03
 */
@Log4j2
@Service
@CacheConfig(cacheNames = "ROLE-SERVICE")
@Transactional(transactionManager = "secondTransactionManager",readOnly = true)
public class SecRoleService {
    @Lazy
    @Autowired
    private SecRoleRepository repository;
    
    /**
     * 【缓存】
     * 缓存整个菜单树
     *
     * @return
     */
    @Cacheable(key = "'TREE:'+#clientId+':full'")
    public List<TreeBean> queryFullTreeFromCache(String clientId) {
        return queryFullTree();
    }
    
    /**
     * 【缓存】
     * 清除缓存
     */
    @CacheEvict(key = "'TREE:'+#clientId+':*'", allEntries = true)
    public void removeCache(String clientId) { }
    
    /**
     * 创建/更新菜单项
     *
     * @param role
     * @return
     */
    @Transactional(transactionManager = "secondTransactionManager")
    public SecRole save(SecRole role) {
        return repository.createOrUpdate(role);
    }
    
    /**
     * 查询整个树
     *
     * @return
     */
    public List<TreeBean> queryFullTree() {
        return TreeUtil.createTree(query(null, null));
    }
    
    /**
     * 根据条件查询菜单项
     *
     * @param parentId 父级ID【EQ】
     * @param name     标题【LIKE】
     * @return
     */
    public List<SecRole> query(Long parentId, String name) {
        return query(parentId, name, null);
    }
    
    /**
     * 【分页】
     * 根据条件查询菜单项
     *
     * @param parentId 父级ID【EQ】
     * @param name     标题【LIKE】
     * @param pager    分页
     * @return
     */
    public List<SecRole> query(Long parentId, String name, Pager pager) {
        QueryFilterList filters = filters(parentId, name);
        OrderList orders = new OrderList();
        orders.addOrder("sort", "ASC");
        return repository.read(filters, orders, pager);
    }
    
    public SecRole queryOne(Long id) {
        return repository.read(id);
    }
    
    /**
     * 查询子节点
     *
     * @param parentId
     * @return
     */
    public List<TreeBean> queryTreeLazy(Long parentId) {
        return TreeUtil.createTree(query(parentId, null));
    }
    
    @Transactional(transactionManager = "secondTransactionManager")
    public void removeRole(List<Long> ids) {
        QueryFilterList filters = new QueryFilterList();
        filters.addFilter("id", Operator.in, ids);
        repository.deleteTreeItemAndAllChildren(filters);
    }
    
    @Transactional(transactionManager = "secondTransactionManager")
    public void removeRole(Long id) {
        QueryFilterList filters = new QueryFilterList();
        filters.addFilter("id", Operator.eq, id);
        repository.deleteTreeItemAndAllChildren(filters);
    }
    
    
    /**
     * 构建条件过滤器
     *
     * @param parentId
     * @param name
     * @return
     */
    private QueryFilterList filters(Long parentId, String name) {
        QueryFilterList filters = new QueryFilterList();
        if (StringUtils.isNotBlank(name)) filters.addFilter("name", Operator.like, name);
        if (Objects.nonNull(parentId)) {
            filters.addFilter("parentId", Operator.eq, parentId);
        }
        return filters;
    }
    
    public List<SecRole> queryDown(List<SecRole> roles) {
        List<SecRole> result = new ArrayList<>();
        roles.forEach(role -> {
            QueryFilterList filters = new QueryFilterList();
            filters.addFilter("supers",Operator.likeL,role.getSupers()+","+role.getId());
            List<SecRole> list = repository.read(filters);
            result.addAll(list);
        });
        return result;
    }
    
    public List<SecRole> queryRoles(Set<Long> roleIds) {
        return repository.read(roleIds);
    }
}
